package com.luo.demo.scg.client.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.oauth2.client.oidc.web.server.logout.OidcClientInitiatedServerLogoutSuccessHandler;
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher;
import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatchers;

/**
 * SpringSecurity OAuth2 Client配置
 *
 * @author luohq
 * @version 1.0.0
 * @date 2022-02-21 10:14
 */
@Configuration
public class Oauth2ClientSecurityConfig {

    /**
     * 需要进行OAuth2 Resource验证的API模式列表
     */
    @Value("${spring.security.oauth2.resourceserver.api-path-mvc-patterns: @null}")
    private String[] apiPathMvcPatterns;

    @Bean
    SecurityWebFilterChain oauth2ClientSecurityFilterChain(ServerHttpSecurity http, OidcClientInitiatedServerLogoutSuccessHandler oidcClientInitiatedServerLogoutSuccessHandler) throws Exception {
        http
                .headers(headers -> headers
                        .frameOptions(frameOptions -> frameOptions
                                .disable()
                        )
                )
                //设置request matcher(仅针对需要进行OAuth Resource验证的API进行拦截)
                //.securityMatcher(this.buildExchangeMatcher())
                //授权设置
                .authorizeExchange(authorize -> authorize
                        //.pathMatchers("/logout", "/front_logout").permitAll()
                        //集成自定义验证器
                        .anyExchange().authenticated()
                )
                .oauth2Login(Customizer.withDefaults())
                .oauth2Client(Customizer.withDefaults())
                .logout(logout -> logout
                        .logoutSuccessHandler(oidcClientInitiatedServerLogoutSuccessHandler)
                );
        return http.build();
    }

    /**
     * 构建请求匹配器
     *
     * @return 请求匹配器
     */
    private ServerWebExchangeMatcher buildExchangeMatcher() {
        if (null == apiPathMvcPatterns || 0 >= apiPathMvcPatterns.length) {
            return ServerWebExchangeMatchers.anyExchange();
        }
        return ServerWebExchangeMatchers.pathMatchers(this.apiPathMvcPatterns);
    }

    /**
     * 单点登录配置
     */
    @Bean
    OidcClientInitiatedServerLogoutSuccessHandler oidcClientInitiatedServerLogoutSuccessHandler (ReactiveClientRegistrationRepository clientRegistrationRepository) {
        OidcClientInitiatedServerLogoutSuccessHandler oidcClientInitiatedLogoutSuccessHandler = new OidcClientInitiatedServerLogoutSuccessHandler(clientRegistrationRepository);
        oidcClientInitiatedLogoutSuccessHandler.setPostLogoutRedirectUri("http://oauth2-scg:8083/");
        return oidcClientInitiatedLogoutSuccessHandler;
    }
}
